package com.musemun.config;


import com.musemun.config.filter.TokenValidateFilter;
import com.musemun.config.filter.UsernamePasswordFilter;
import com.musemun.config.handler.LoginSuccessHandler;
import com.musemun.config.handler.LogoutSuccessHandler;

import com.musemun.service.function.functionimpl.EmployeeDetailService;
import com.musemun.util.JwtTokenUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.util.DigestUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;
import java.net.MalformedURLException;
import java.net.URL;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    EmployeeDetailService employeeDetailService;
    Logger log = LoggerFactory.getLogger(LoginSuccessHandler.class);
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.cors().and()
                .authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
                .and().csrf().disable()
                .addFilterAt(usernamePasswordFilter(),UsernamePasswordAuthenticationFilter.class)
//                .addFilterBefore(responseFilter(), ChannelProcessingFilter.class)
                .addFilterBefore( getTokenValidateFilter(), UsernamePasswordAuthenticationFilter.class)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .antMatchers("/login_url","/logout_url","/two_dimensional_code/generator_image/**","/query_role/**","/two_dimensional_code/by_image/**").permitAll()
                .anyRequest().authenticated()
                .and()
//                .formLogin().loginPage("/login_url").loginProcessingUrl("/login_url").failureUrl("/fail_url")
//                .successHandler(getLoginSuccessHandler())
//                .and()
                .logout().logoutUrl("/logout_url")
                .logoutSuccessHandler(getLogoutSuccessHandler());

    }

    @Override
    public void configure(WebSecurity web){
       web.ignoring().antMatchers("/js/**","/css/**","/fail_url","/static/**","/img/**","/img/carousel/**","/swagger-ui.html","/webjars/**","/v2/**","/swagger-resources/**");
    }

    /**
     *
     *    对密码惊醒加密
     * @param auth
     * @return void
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//        log.info(JSON.toJSONString(auth));
        System.out.println(auth);
        //校验用户
        auth.userDetailsService( employeeDetailService ).passwordEncoder( new PasswordEncoder() {
            //对密码进行加密
            @Override
            public String encode(CharSequence charSequence) {
                System.out.println(charSequence.toString());
                return DigestUtils.md5DigestAsHex(charSequence.toString().getBytes());
            }
            //对密码进行判断匹配
            @Override
            public boolean matches(CharSequence charSequence, String s) {
                String encode = DigestUtils.md5DigestAsHex(charSequence.toString().getBytes());
                return s.equals( encode );
            }
        } );
    }

    @Override
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

    @Bean
    public LoginSuccessHandler getLoginSuccessHandler(){
        return new LoginSuccessHandler();
    }

    @Bean
    public TokenValidateFilter getTokenValidateFilter(){return new TokenValidateFilter();}

    @Bean
    public JwtTokenUtil getJwtTokenUtil(){return new JwtTokenUtil();}

    @Bean
    public LogoutSuccessHandler getLogoutSuccessHandler(){return new LogoutSuccessHandler();}

//    @Bean
//    public CorsConfigurationSource CorsConfigurationSource() {
//        UrlBasedCorsConfigurationSource source =   new UrlBasedCorsConfigurationSource();
//        CorsConfiguration corsConfiguration = new CorsConfiguration();
//        corsConfiguration.addAllowedOrigin("*");	//同源配置，*表示任何请求都视为同源，若需指定ip和端口可以改为如“localhost：8080”，多个以“，”分隔；
//        corsConfiguration.addAllowedHeader("*");//header，允许哪些header，本案中使用的是token，此处可将*替换为token；
//        corsConfiguration.addAllowedMethod("*");	//允许的请求方法，PSOT、GET等
//        source.registerCorsConfiguration("/**",corsConfiguration); //配置允许跨域访问的url
//        return source;
//    }
    @Bean
    public CorsFilter corsFilter()  {
        final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new  UrlBasedCorsConfigurationSource();
        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setMaxAge((long) 3000000);
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
    @Bean
    public HttpFirewall allowUrlSemicolonHttpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        firewall.setAllowSemicolon(true);
        return firewall;
    }
    @Bean
    public UsernamePasswordFilter usernamePasswordFilter() throws Exception {
        UsernamePasswordFilter filter=new UsernamePasswordFilter();
        filter.setAuthenticationManager(super.authenticationManager());
        filter.setFilterProcessesUrl("/login_url");
        filter.setAuthenticationSuccessHandler(getLoginSuccessHandler());
        return filter;
    }

}
